home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************\
-
- File: ls load-save.c
-
- Purpose: This module handles loading and saving games on disk.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program in a file named "GNU General Public License".
- If not, write to the Free Software Foundation, 675 Mass Ave,
- Cambridge, MA 02139, USA.
-
- \**********************************************************************/
-
- #include "error.h"
- #include "ls load-save.h"
- #include "file interface.h"
- #include "ls.h"
- #include "program globals.h"
- #include "dialogs.h"
- #include "environment.h"
- #include "util.h"
- #include "Script.h"
-
- FSSpec gameFile;
- Boolean deleteTheThing;
-
- typedef struct
- {
- unsigned short version; /* for forward compatibility */
- unsigned short crc; /* checksum */
-
- short numRows; /* number of rows in saved board */
- short numColumns; /* number of columns in saved board */
- short currentRow; /* currently highlighted row */
- short currentColumn; /* currently highlighted column */
- short numMoves; /* number of moves so far */
- short theboard[MAX_ROWS][MAX_COLS]; /* actual board */
- Point themoves[MAX_ROWS*MAX_COLS]; /* all moves array */
- } SaveStruct;
-
- void InitLoadSave(void)
- {
- gameFile.name[0]=0x00;
- deleteTheThing=FALSE;
- }
-
- void LoadSaveDispatch(Boolean isLoad, Boolean useOldGame)
- {
- if (isLoad)
- {
- if (GetSourceFile(&gameFile, FALSE, FALSE))
- HandleError(GetSavedGame(&gameFile), FALSE);
- }
- else
- {
- useOldGame=useOldGame&&(gameFile.name[0]!=0x00);
- if (useOldGame ? TRUE : GetDestFile(&gameFile, &deleteTheThing, "\pSave game as..."))
- HandleError(SaveGame(gameFile), FALSE);
- }
- }
-
- enum ErrorTypes SaveGame(FSSpec gameFile)
- {
- OSErr theError;
- short thisFile;
- long count;
- SaveStruct data;
- short i,j;
-
- data.numRows=gNumRows;
- data.numColumns=gNumColumns;
- data.currentRow=gCurrentRow;
- data.currentColumn=gCurrentColumn;
- for (i=0; i<MAX_ROWS; i++)
- for (j=0; j<MAX_COLS; j++)
- data.theboard[i][j]=Board[i][j];
- for (i=0; i<MAX_ROWS*MAX_COLS; i++)
- data.themoves[i]=gMoves[i];
- data.version=SAVE_VERSION;
- data.crc=0;
- data.crc=TheChecksum((Ptr)(&data), sizeof(SaveStruct));
-
- if (deleteTheThing)
- {
- if (gHasFSSpecs)
- FSpDelete(&gameFile);
- else
- HDelete(gameFile.vRefNum, gameFile.parID, gameFile.name);
- }
- FlushVol(0L, gameFile.vRefNum);
-
- if (gHasFSSpecs)
- theError=FSpCreate(&gameFile, CREATOR, SAVE_TYPE, smSystemScript);
- else
- theError=HCreate(gameFile.vRefNum, gameFile.parID,
- gameFile.name, CREATOR, SAVE_TYPE);
- FlushVol(0L, gameFile.vRefNum);
-
- if (theError!=noErr)
- return kCantCreateGame;
-
- if (gHasFSSpecs)
- theError=FSpOpenDF(&gameFile, fsRdWrPerm, &thisFile);
- else
- theError=HOpen(gameFile.vRefNum, gameFile.parID,
- gameFile.name, fsRdWrPerm, &thisFile);
-
- if (theError!=noErr)
- return kCantOpenGameToSave;
-
- count=sizeof(SaveStruct);
- theError=SetEOF(thisFile, count);
- if (theError!=noErr)
- {
- FSClose(thisFile);
- return kDiskFull;
- }
-
- SetFPos(thisFile, 1, 0L);
- theError=FSWrite(thisFile, &count, &data);
-
- FSClose(thisFile);
- FlushVol(0L, gameFile.vRefNum);
-
- if (theError!=noErr)
- {
- if (gHasFSSpecs)
- FSpDelete(&gameFile);
- else
- HDelete(gameFile.vRefNum, gameFile.parID, gameFile.name);
-
- gameFile.name[0]=0x00;
- return kCantWriteGame;
- }
- else deleteTheThing=TRUE;
-
- return allsWell;
- }
-
- enum ErrorTypes GetSavedGame(FSSpec *gameFile)
- {
- short thisFile;
- long count;
- short i,j;
- SaveStruct data;
- OSErr theError;
- unsigned short checksum, savedChecksum;
-
- if (gHasFSSpecs)
- theError=FSpOpenDF(gameFile, fsRdPerm, &thisFile);
- else
- theError=HOpen(gameFile->vRefNum, gameFile->parID, gameFile->name, fsRdPerm, &thisFile);
-
- if (theError!=noErr)
- return kCantOpenGameToLoad;
-
- count=sizeof(SaveStruct);
- SetFPos(thisFile, 1, 0L);
- theError=FSRead(thisFile, &count, &data);
- FSClose(thisFile);
-
- if (theError!=noErr)
- return kCantLoadGame;
-
- deleteTheThing=TRUE;
-
- if (data.version!=SAVE_VERSION)
- return kSaveVersionNotSupported;
-
- savedChecksum=data.crc;
- data.crc=0;
- checksum=TheChecksum((Ptr)(&data), sizeof(SaveStruct));
- if (checksum!=savedChecksum)
- {
- gameFile->name[0]=0x00;
- return kBadChecksum;
- }
-
- gNumRows=data.numRows;
- gNumColumns=data.numColumns;
- gCurrentRow=data.currentRow;
- gCurrentColumn=data.currentColumn;
- gNumMoves=data.numMoves;
- for (i=0; i<MAX_ROWS; i++)
- for (j=0; j<MAX_COLS; j++)
- Board[i][j]=data.theboard[i][j];
- for (i=0; i<MAX_ROWS*MAX_COLS; i++)
- gMoves[i]=data.themoves[i];
-
- StartGame();
-
- return allsWell;
- }
-
- unsigned short TheChecksum(Ptr input, unsigned short len)
- {
- unsigned short i;
- Boolean shiftedOut;
- unsigned short checksum;
-
- checksum=0;
- for (i=0; i<len; i++)
- {
- shiftedOut=checksum&0x8000;
- checksum+=*((unsigned char*)((long)input+i));
- checksum<<=1;
- if (shiftedOut)
- checksum^=0xdead;
- }
-
- return checksum;
- }
-